package org.jrfe.scene.impl;

import java.util.LinkedList;

import org.jrfe.math.Transform2D;
import org.jrfe.math.Vector2f;
import org.jrfe.math.bound.Bound;
import org.jrfe.math.bound.BoundRect;
import org.jrfe.scene.QueryCal;

public class Node extends BaseNode {
	
	LinkedList<BaseNode> childes = new LinkedList<BaseNode>();
	
	public Node() {
		setBound(new BoundRect());
	}

	public void add(BaseNode base) {
		childes.add(base);
		base.setParent(this);
	}

	public void remove(BaseNode base) {
		if (childes.remove(base)) {
			base.setParent(null);
		}
	}

	public void getList(LinkedList<Leaf> leafs, BoundRect interRecht) {
		for (BaseNode base : childes) {
			if (base instanceof Node) {
				Node n = (Node) base;
				if (interRecht.intersects(n.getBound())) {
					n.getList(leafs, interRecht);
				}
			} else {
				Leaf l = (Leaf) base;
				if (interRecht.intersects(l.getBound())) {
					leafs.add(l);
				}
			}
		}
	}
	
	public void getList(LinkedList<Leaf> leafs, BoundRect interRecht,QueryCal type,int mask) {
		for (BaseNode base : childes) {
			if (base instanceof Node) {
				Node n = (Node) base;
				if (interRecht.intersects(n.getBound())) {
					n.getList(leafs, interRecht);
				}
			} else {
				Leaf l = (Leaf) base;
				if(type.cals(mask, l.getMask())){
					if (interRecht.intersects(l.getBound())) {
						leafs.add(l);
					}
				}
			}
		}
	}
	
	@Override
	public void translate(Vector2f v) {
		worldCenter.add(v);
		if(getParent() != null){
			localCenter.set(worldCenter.x - getParent().getWorldCenter().x, worldCenter.y - getParent().getWorldCenter().y);
		}else{
			localCenter.set(worldCenter);
		}
		for (BaseNode base : childes) {
			base.translate(v);
		}
		
		applayTranslate();
	}
	
	@Override
	public void transform(Transform2D t) {
		//worldTransform.add(t);
		/*if(getParent() != null){
			localTransform.setRotate(worldTransform.getRotate() - getParent().getWorldTransform().getRotate()); 
		}else{
			localTransform.setTo(worldTransform);
		}*/
		
		//Vector2f tmp = new Vector2f(); 
		
		for (BaseNode base : childes) {
			base.transform(t);
		/*	float oldx = base.getLocalCenter().x;
			float oldy = base.getLocalCenter().y;
			
			float x = oldx * worldTransform.getCosAngle() - oldy * worldTransform.getSinAngle();
			float y = oldx * worldTransform.getSinAngle() + oldy * worldTransform.getCosAngle();
			tmp.setTo(x - base.worldCenter.x, y - base.worldCenter.y);
			base.translate(tmp);
		*/
		}
		
		applayTransform();
	}
	
	@Override
	public void applayTranslate() {
		getBound().center.set(getWorldCenter());
	}
	
	
	@Override
	public void updateBound(){
		boolean set = false;
		float x = 0;
		float y = 0;
		float x2 = 0;
		float y2 = 0;
	
		for(BaseNode base : childes){
			
			Bound br = base.getBound();
			Vector2f center = br.center;
			if(!set){
				x = center.x - br.xExtent;
				y = center.y - br.yExtent;
				x2 = center.x + br.xExtent;
				y2 = center.y + br.yExtent;
				set = true;
			}
			else{
				x = Math.min(x, center.x - br.xExtent);
				y = Math.min(y, center.y - br.yExtent);
				x2 = Math.max(x2, center.x + br.xExtent);
				y2 = Math.max(y2, center.y + br.yExtent);
				 
			}
		}
		
		getBound().update(x, y, x2, y2);
		if(getParent() != null){
			getParent().updateBound();
		}
	}
	
}
